// Copyright (c) 2005  INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of cgal-python; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; version 2.1 of the License.
// See the file LICENSE.LGPL distributed with cgal-python.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $Id: Py_Gmpq.cpp 165 2007-11-02 14:35:12Z spion $
// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal-python/trunk/cgal-python/bindings/Kernel/Py_Gmpq.cpp $
//
// Author(s)     : Naceur Meskini
//=========================================================================

#include <CGAL/basic.h>
#include <CGAL/Gmpq.h>
#include <CGAL/Lazy_exact_nt.h>

#include <boost/python.hpp>
#include <boost/cstdint.hpp>

using namespace boost::python;

template <class Lazy_exact_nt> 
double to_double(const Lazy_exact_nt& NT)
{
	return CGAL::to_double(NT);
}

void export_Gmpq()
{
const char* Gmpq_doc = "An object of the class Gmpq is an arbitrary precision rational \n\
number based on the GNU Multiple Precision Arithmetic Library.\n\n\
For more details see:\n\
http://www.cgal.org/Manual/3.2/doc_html/cgal_manual/NumberTypeSupport_ref/Class_Gmpq.html";

	typedef CGAL::Lazy_exact_nt<CGAL::Gmpq> Lazy_exact_nt;

    class_< Lazy_exact_nt >("FT", init< >())
        .def(init< const CGAL::Gmpq& >())
        .def(init< const Lazy_exact_nt& >())
        .def(init< const int& >())
        .def(init< const double& >())
	.def("exact", &Lazy_exact_nt::exact,return_value_policy< copy_const_reference >())
        .def("to_double", &to_double<Lazy_exact_nt>)
        .def( other< int >() > self )
        .def( self >= other< int >() )
        .def( self * other< int >() )
        .def( self / other< int >() )
        .def( other< int >() - self )
        .def( other< int >() * self )
        .def( other< int >() <= self )
        .def( other< int >() < self )
        .def( other< int >() / self )
        .def( other< int >() >= self )
        .def( self + self )
        .def( self != other< int >() )
        .def( self <= other< int >() )
        .def( other< int >() != self )
        .def( other< int >() + self )
        .def( self != self )
        .def( self > self )
        .def( self <= self )
        .def( self >= self )
        .def( self / self )
        .def( self < other< int >() )
        .def( other< int >() == self )
        .def( self == self )
        .def( self < self )
        .def( self == other< int >() )
        .def( self > other< int >() )
        .def( self - self )
        .def( self - other< int >() )
        .def( self + other< int >() )
        .def( self * self )
        .def( -self )
        .def( self += self )
        .def( self -= self )
        .def( self *= self )
        .def( self /= self )
	;

    class_< CGAL::Gmpq >("Gmpq",Gmpq_doc, init<  >())
        .def(init< const CGAL::Gmpq& >())
        .def(init< const __mpq_struct* >())
        .def(init< int >())
        .def(init< long int >())
        .def(init< long unsigned int >())
        .def(init< const CGAL::Gmpz& >())
        .def(init< int, int >())
        .def(init< long int, long unsigned int >())
        .def(init< long unsigned int, long unsigned int >())
        .def(init< const CGAL::Gmpz&, const CGAL::Gmpz& >())
        .def(init< double >())
        .def(init< const std::string&, optional< int > >())
        .def("numerator", &CGAL::Gmpq::numerator)
        .def("denominator", &CGAL::Gmpq::denominator)
        .def("to_double", &CGAL::Gmpq::to_double)
        .def("sign", &CGAL::Gmpq::sign)
        .def( other< int >() > self )
        .def( self >= other< int >() )
        .def( self * other< int >() )
        .def( self / other< int >() )
        .def( other< int >() - self )
        .def( other< int >() * self )
        .def( other< int >() <= self )
        .def( other< int >() < self )
        .def( other< int >() / self )
        .def( other< int >() >= self )
        .def( self + self )
        .def( self != other< int >() )
        .def( self <= other< int >() )
        .def( other< int >() != self )
        .def( other< int >() + self )
        .def( self != self )
        .def( self > self )
        .def( self <= self )
        .def( self >= self )
        .def( self / self )
        .def( self < other< int >() )
        .def( other< int >() == self )
        .def( self == self )
        .def( self < self )
        .def( self == other< int >() )
        .def( self > other< int >() )
        .def( self - self )
        .def( self - other< int >() )
        .def( self + other< int >() )
        .def( self * self )
        .def( -self )
        .def( self += self )
        .def( self -= self )
        .def( self *= self )
        .def( self /= self )
    ;

const char* Gmpz_doc ="\
An object of the class Gmpz is an arbitrary precision integer based on the GNU Multiple Precision Arithmetic Library.\n\
For more details see:\n\
http://www.cgal.org/Manual/3.2/doc_html/cgal_manual/NumberTypeSupport_ref/Class_Gmpz.html";

    class_< CGAL::Gmpz >("Gmpz",Gmpz_doc,init<>())
        .def(init< const CGAL::Gmpz& >())
        .def(init< int >())
        .def(init< long int >())
        .def(init< long unsigned int >())
        .def(init< double >())
        .def(init< const std::string&, optional< int > >())
        .def("approximate_decimal_length", &CGAL::Gmpz::approximate_decimal_length)
        .def("to_double", &CGAL::Gmpz::to_double)
        .def("sign", &CGAL::Gmpz::sign)
        .def( self == other< CGAL::Quotient<CGAL::Gmpz> >() )
        .def( self < other< CGAL::Quotient<CGAL::Gmpz> >() )
        .def( self > other< CGAL::Quotient<CGAL::Gmpz> >() )
        .def( self >= other< CGAL::Quotient<CGAL::Gmpz> >() )
        .def( self <= other< CGAL::Quotient<CGAL::Gmpz> >() )
        .def( other< CGAL::Quotient<CGAL::Gmpz> >() != self )
        .def( self != other< CGAL::Quotient<CGAL::Gmpz> >() )
        .def( other< CGAL::Quotient<CGAL::Gmpz> >() >= self )
        .def( other< CGAL::Quotient<CGAL::Gmpz> >() <= self )
        .def( self < self )
        .def( self <= self )
        .def( self * other< CGAL::Quotient<CGAL::Gmpz> >() )
        .def( self - other< CGAL::Quotient<CGAL::Gmpz> >() )
        .def( other< CGAL::Quotient<CGAL::Gmpz> >() - self )
        .def( self + other< CGAL::Quotient<CGAL::Gmpz> >() )
        .def( self / other< int >() )
        .def( self / self )
        .def( self * self )
        .def( self - self )
        .def( self + self )
        .def( other< int >() < self )
        .def( other< int >() >= self )
        .def( self % self )
        .def( self >= other< int >() )
        .def( other< int >() > self )
        .def( other< CGAL::Quotient<CGAL::Gmpz> >() * self )
        .def( other< CGAL::Quotient<CGAL::Gmpz> >() + self )
        .def( self / other< CGAL::Quotient<CGAL::Gmpz> >() )
        .def( other< CGAL::Quotient<CGAL::Gmpz> >() / self )
        .def( self == other< int >() )
        .def( self > other< int >() )
        .def( self == self )
        .def( self < other< int >() )
        .def( other< int >() / self )
        .def( other< int >() % self )
        .def( self % other< int >() )
        .def( other< int >() - self )
        .def( self + other< int >() )
        .def( other< int >() != self )
        .def( other< int >() == self )
        .def( self <= other< int >() )
        .def( other< int >() <= self )
        .def( self - other< int >() )
        .def( other< int >() + self )
        .def( self != other< int >() )
        .def( other< int >() * self )
        .def( self * other< int >() )
        .def( self >= self )
        .def( self > self )
        .def( self != self )
        .def( -self )
        .def( self += self )
        .def( self += other< int >() )
        .def( self -= self )
        .def( self -= other< int >() )
        .def( self *= self )
        .def( self *= other< int >() )
        .def( self %= self )
        .def( self /= self )
        .def( self /= other< int >() )
    ;
}
